package org.bronycorps.mlptss.domain.layer;

import java.util.ArrayList;
import java.util.List;

import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Polygon;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;

public class DebugLayer {

	private class DebugCircle extends DebugShape {
		Vector2 position;
		Float radius;

		public DebugCircle(Vector2 position, Float radius) {
			super();
			this.position = position;
			this.radius = radius;
		}

		@Override
		public void draw(ShapeRenderer render) {
			render.begin(ShapeType.Line);
			render.circle(this.position.x, this.position.y, this.radius);
			render.end();
		}

	}

	private class DebugLine extends DebugShape {
		Vector2 start, end;

		public DebugLine(Vector2 start, Vector2 end) {
			this.start = start;
			this.end = end;
		}

		@Override
		public void draw(ShapeRenderer render) {
			render.begin(ShapeType.Line);
			render.line(this.start.x, this.start.y + 300, this.end.x,
					this.end.y + 300);
			render.end();
		}
	}

	private class DebugPoint extends DebugShape {
		Vector2 position;

		public DebugPoint(Vector2 position) {
			super();
			this.position = position;
		}

		@Override
		public void draw(ShapeRenderer render) {
			render.begin(ShapeType.Point);
			render.point(this.position.x, this.position.y, 0);
			render.end();

		}

	}

	private class DebugPoly extends DebugShape {
		Polygon poly;

		public DebugPoly(Polygon poly) {
			super();
			this.poly = poly;
		}

		@Override
		public void draw(ShapeRenderer render) {
			render.begin(ShapeType.Line);
			Float x = null;
			Float y = null;
			Float prevx = null;
			Float prevy = null;
			final float[] values = this.poly.getTransformedVertices();
			for (float value : values) {
				if (x == null) {
					x = value;
				} else {
					y = value;
					if (prevy != null) {
						render.line(prevx, prevy, x, y);
					}
					prevx = x;
					prevy = y;
					x = null;
				}
			}
			render.line(prevx, prevy, values[0], values[1]);
			render.end();
		}
	}

	private class DebugRect extends DebugShape {
		Rectangle rect;

		public DebugRect(Rectangle rect) {
			super();
			this.rect = rect;
		}

		@Override
		public void draw(ShapeRenderer render) {
			render.begin(ShapeType.Line);
			render.rect(this.rect.x, this.rect.y, this.rect.width,
					this.rect.height);
			render.end();
		}
	}

	private abstract class DebugShape {
		public abstract void draw(ShapeRenderer render);
	}

	private static DebugLayer instance = null;

	public static DebugLayer getInstance() {
		if (instance == null) {
			instance = new DebugLayer();
		}
		return instance;
	}

	private List<DebugShape> shapes = new ArrayList<DebugLayer.DebugShape>();

	private DebugLayer() {

	}

	public void clear() {
		this.shapes.clear();
	}

	public void createCircle(Vector2 position, Float radius) {
		this.shapes.add(new DebugCircle(position, radius));
	}

	public void createLine(Vector2 start, Vector2 end) {
		this.shapes.add(new DebugLine(start, end));
	}

	public void createPoint(Vector2 position) {
		this.shapes.add(new DebugPoint(position));
	}

	public void createPolygon(Polygon poly) {
		this.shapes.add(new DebugPoly(poly));
	}

	public void createRect(Rectangle rect) {
		this.shapes.add(new DebugRect(rect));
	}

	public void draw(ShapeRenderer render) {
		for (DebugShape shape : this.shapes) {
			shape.draw(render);
		}
	}
}
